package easydst;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;

import exception.ResultException;

import util.Msg;

public class TestAgentImpl extends UnicastRemoteObject implements TestAgent {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	Map<Component, String> componentsAndFacade;
		

	public TestAgentImpl() throws RemoteException {
		super();
		Msg.debug("Into constructor of TestAgentImpl");
		componentsAndFacade = new HashMap<Component, String>();
	}

	@Override
	public Object executeComponent(Component component, String method,
			String... args) throws RemoteException, ResultException {

//		TestAgentServer.main(args); TODO exemplo de como chamar o metodo main de uma outra classe!
		Msg.debug("Into execute Component");
		
		String command = "java -cp " + component.getClasspath() + " " + component.getAccessPoint() + " " + method; 
		for (String arg : args) {
			command += " " + arg;
		}

		// executing the command
		ProcessExecution execution = new ProcessExecution(command);
		execution.execute();
				
		Msg.debug(execution.getCommandOutput().toString());//TODO
		try {
			Result result = (Result) Naming.lookup( Constants.RMI_LOCALHOST + Constants.RESULT_NAME);
			return result.getResult();
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new ResultException(e.getMessage());		
		}	
	}

	@Override
	public void executeCommand(String command, String... args)
			throws RemoteException {
		
		Msg.debug("The method executeCommand was called at TestAgentImpl");
		// adding the arguments to the command
		String completeCommand = command;
		for (String arg : args) {
			completeCommand += " " + arg;
		}

		Msg.debug("Into method executeCommand before execution");
		// executing the command
		ProcessExecution execution = new ProcessExecution(completeCommand);
		execution.execute();
		
		Msg.debug("Into method executeCommand after execution");
	}

}
